



function Engine()
{
  BaseStyles.call(this);
  BaseInteraction.call(this,this.coordinateConversionCallback);
  BaseAssets.call(this);
}

Engine.inherit(BaseStyles);
Engine.inherit(BaseInteraction);
Engine.inherit(BaseAssets);

Engine.prototype.coordinateConversionCallback = function (layer, point)
{
  //return $V(point.x,layer.size.y-point.y);
  return point;
}

Engine.prototype.drawLine = function (layer,style,point1,point2)
{
  this.getLayer(layer).drawLine(this.getStyle(style),point1,point2);
  
  if(this.isTopLayer(layer) && this.hasClickLayer() && this.hasGizmo())
  {
    var tempStyle = this.getStyle(style).clone();
    tempStyle.strokeColour = this.currentGizmo.colour;
    this.clickLayer.drawRect(tempStyle,point1,point2);
  }
}

Engine.prototype.drawRect = function (layer,style,point1,point2)
{
  this.getLayer(layer).drawRect(this.getStyle(style),point1,point2);
  
  if(this.isTopLayer(layer) && this.hasClickLayer() && this.hasGizmo())
  {
    var tempStyle = this.getStyle(style).clone();
    tempStyle.fillColour = this.currentGizmo.colour;
    tempStyle.strokeColour = this.currentGizmo.colour;
    this.clickLayer.drawRect(tempStyle,point1,point2);
  }
}

Engine.prototype.clearRect = function (layer,point1,point2)
{
  this.getLayer(layer).clearRect(point1,point2);
  
  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.clearRect(point1,point2);
}

Engine.prototype.drawImage = function (layer,asset,point1,point2)
{
  this.getLayer(layer).drawImage(this.getAsset(asset),point1,point2);
  
  if(this.isTopLayer(layer) && this.hasClickLayer() && this.hasGizmo())
  {
    this.clickLayer.drawImage(this.getAsset(asset),point1,point2);
    
    var pixels = this.clickLayer.getImageData(point1,point2);
    var colour = this.currentGizmo.colour;
    for(var i=0;i<pixels.data.length;i+=4)
    {
      if(pixels.data[i+3] != 0)
      {
        pixels.data[i] = colour.r;
        pixels.data[i+1] = colour.g;
        pixels.data[i+2] = colour.b;
        pixels.data[i+3] = 255;
      }
    }
    
    this.clickLayer.clearRect(point1,point2);
    this.clickLayer.putImageData(pixels,point1);
  }
}

Engine.prototype.drawText = function (layer,style,text,point)
{
  this.getLayer(layer).drawText(this.getStyle(style),text,point);
  
  if(this.isTopLayer(layer) && this.hasClickLayer() && this.hasGizmo())
  {
    var tempStyle = this.getStyle(style).clone();
    tempStyle.fillColour = this.currentGizmo.colour;
    tempStyle.strokeColour = this.currentGizmo.colour;
    
    this.clickLayer.drawText(tempStyle,text,point);    
  }
}

Engine.prototype.save = function (layer)
{
  this.getLayer(layer).save();
  
  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.save();
}

Engine.prototype.restore = function (layer)
{
  this.getLayer(layer).restore();

  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.restore();
    
  this.loadMatrix(layer);
}

Engine.prototype.translate = function (layer,point)
{
  this.getLayer(layer).translate(point);
      
  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.translate(point);
    
  this.loadMatrix(layer);    
}

Engine.prototype.rotate = function (layer, angle)
{
  this.getLayer(layer).rotate(angle);
        
  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.rotate(angle);
    
  this.loadMatrix(layer);
}  

Engine.prototype.setTransformMatrix = function (layer,m11,m12,m21,m22,x,y)
{
  this.getLayer(layer).setTransformMatrix(m11,m12,m21,m22,x,y);
  
  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.setTransformMatrix(m11,m12,m21,m22,x,y);
    
  this.loadMatrix(layer);
}

Engine.prototype.loadMatrix = function (layer)
{
  this.getLayer(layer).loadMatrix();
  
  if(this.isTopLayer(layer) && this.hasClickLayer())
    this.clickLayer.loadMatrix();
  
}

/*
var e = new Engine();

function init()
{
  
  e.addLayer('bg');
  e.addLayer('fg');
  e.addClickLayer('click');
  
  e.addStyle('red',new FillStyle(rgb(255,0,0)));
  e.addStyle('blue',new FillStyle(rgb(0,0,255)));
  e.addStyle('black line', new StrokeStyle(rgb(0,0,0),5));
  e.addStyle('black stroke font', new StrokeFontStyle(rgb(0,0,0),1,'20px Arial'));
  e.addStyle('green fill font', new FillFontStyle(rgb(0,255,0),'30px Arial'));
  e.addStyle('black fill font', new FillFontStyle(rgb(0,0,0),'40px Arial'));
  
  e.addImage('title','Images/title.png');
  e.addImage('title2','Images/title2.png');
  e.addAudio('theme','Audio/test.ogg');
  e.loadAssets(preloadComplete);
  
  e.clearGizmos();
  e.addGizmo(new Gizmo('Blueie',gizmoCallback,gizmoCallback,gizmoCallback,gizmoCallback));
  e.addGizmo(new Gizmo('Lines',gizmoCallback,gizmoCallback,gizmoCallback,gizmoCallback));
  e.addGizmo(new Gizmo('Title',gizmoCallback,gizmoCallback,gizmoCallback,gizmoCallback));
  e.addGizmo(new Gizmo('Name',gizmoCallback,gizmoCallback,gizmoCallback,gizmoCallback));
  
}

function preloadComplete()
{
  e.setupInteraction();
  
  e.addHook('MouseMove',mouseMoveHook);
  
  e.startInteraction();
  setInterval('draw()',1);
  //draw();
}

function draw()
{
  
  e.clearRect(0,$V(0,0),$V(640,480));
  
  e.drawRect(0,'red',$V(0,0),$V(100,100));
  e.drawLine(0,'black line',$V(0,50),$V(640,50));
  e.drawLine(0,'black line',$V(50,0),$V(50,480));
  e.drawImage(0,'title',$V(200,200),$V(300,300));
  e.drawText(0,'black stroke font','Boris',$V(400,200));
  
  e.clearRect(1,$V(0,0),$V(640,480));
  
  
  e.startGizmo('Blueie');
  e.drawRect(1,'blue',$V(100,100),$V(200,200));
  e.stopGizmo();
  
  e.startGizmo('Lines');
  e.drawLine(1,'black line',$V(0,150),$V(640,150));
  e.drawLine(1,'black line',$V(150,0),$V(150,480));
  e.stopGizmo();
  
  e.startGizmo('Title');
  e.drawImage(1,'title2',$V(300,300),$V(400,400));
  e.stopGizmo();
  
  e.startGizmo('Name');
  e.drawText(1,'green fill font','Michael',$V(100,200));
  e.stopGizmo();
}

function gizmoCallback(type,name,point)
{
  e.drawText(1,'black fill font',type + ': ' + name,$V(0,0));
}

function mouseMoveHook(point)
{
  var point2 = point.add($V(10,10));
  
  //e.clearRect(1,$V(0,0),$V(640,480));
  //e.drawRect(1,'red',point,point2);  
}
*/
